#include "notifywnd.h"

TopBar::TopBar(QWidget *p) : QFrame(p) {
    this->setObjectName("TopBarWnd");
    initUI();
}

TopBar::~TopBar() {}

void TopBar::initUI () {
    _settingsBtn = new QPushButton(tr("Settings"), this);
    _settingsBtn->setObjectName("TopBar_SettingsBtn");
    _hideBtn = new QPushButton(this);
    _hideBtn->setObjectName("TopBar_HideBtn");
    QLabel *lab = new QLabel(this);
    lab->setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Fixed);
    lab->setMaximumWidth (300);
    QHBoxLayout *hb = new QHBoxLayout;
    hb->setMargin (0);
    hb->addWidget(_hideBtn);
    hb->addStretch (100);
    hb->addWidget (lab);
    hb->addWidget (_settingsBtn, Qt::AlignRight);
    hb->setContentsMargins (1, 1, 1, 1);
    this->setMaximumHeight (80);
    this->setLayout (hb);

    connect(_hideBtn, &QPushButton::clicked, this, [&] {emit hideWnd(); });
    connect(_settingsBtn, &QPushButton::clicked, this, [&] {emit showSettingsWnd(); });
}

FootAreaWnd::FootAreaWnd(QWidget *p) : QFrame(p) {
    this->setObjectName("FootBarWnd");
    initUI();
    initMainWnd ();
}

FootAreaWnd::~FootAreaWnd () {}

void FootAreaWnd::initUI () {
    QPushButton *hideBtn = new QPushButton(tr("Hide"), this);
    QHBoxLayout *hb = new QHBoxLayout;
    hb->addWidget (hideBtn);
    hb->addStretch (300);

    _mainWnd = new QWidget(this);
    QVBoxLayout *vb = new QVBoxLayout;
    vb->addLayout (hb);
    vb->addWidget (_mainWnd);

    this->setLayout (vb);
    connect (hideBtn, &QPushButton::clicked, [=]{
        _mainWnd->isHidden () ? showMainWnd () : hideMainWnd ();
    });
}

void FootAreaWnd::initMainWnd () {
    QPushButton *b1 = new QPushButton("A", this);
    QPushButton *b2 = new QPushButton("B", this);
    QHBoxLayout *hb = new QHBoxLayout;
    hb->addWidget (b1);
    hb->addWidget (b2);
    _mainWnd->setLayout (hb);
}

void FootAreaWnd::showMainWnd () {
    // QPropertyAnimation *act = new QPropertyAnimation(_mainWnd, "geometry");
    _mainWnd->show ();
    /*act->setDuration (200);
    act->setStartValue (_mainWnd->geometry ());
    act->setEndValue (QRect(_mainWnd->x (), _mainWnd->y () - 200,
                            _mainWnd->width (), _mainWnd->height ()+200));
    act->setEasingCurve (QEasingCurve::InCubic);
    act->start (QAbstractAnimation::DeleteWhenStopped);*/
}

void FootAreaWnd::hideMainWnd () {
    _mainWnd->hide();
    // QPropertyAnimation *act = new QPropertyAnimation(_mainWnd, "geometry");
    /*_mainWnd->show ();
    act->setDuration (200);
    act->setStartValue (_mainWnd->geometry ());
    act->setEndValue (QRect(_mainWnd->x (), _mainWnd->y () + 200,
                            _mainWnd->width (), 0));
    act->setEasingCurve (QEasingCurve::InCubic);
    act->start (QAbstractAnimation::DeleteWhenStopped);
    connect (act, &QPropertyAnimation::finished, [=]{_mainWnd->hide ();});*/
}

NotifyWnd::NotifyWnd(QWidget *p) : QWidget(p) {
    this->setObjectName("NotifyWnd");
    this->hide ();
    qApp->installEventFilter (this);
    setWindowFlags (Qt::Tool);
    setMouseTracking (true);
    initUI();
    initMainWnd();
    initSettingsWnd();
    initSystemTray();
    loadLocalData();
    this->raise();
    _isShow = false;
    _atom = GlobalAddAtom(L"a");
    if (RegisterHotKey((HWND)winId(), _atom, MOD_ALT, VK_F8)) {
        qApp->installNativeEventFilter(this);
    }
}

NotifyWnd::~NotifyWnd () {
    saveLocalData();
    UnregisterHotKey((HWND)winId(), _atom);
    GlobalDeleteAtom(_atom);
}

void NotifyWnd::initUI () {
    _mainWnd = new QWidget(this);
    _settingsWnd = new CSettingsWnd(this);
    _stackedLayout = new QStackedLayout();
    _stackedLayout->addWidget(_mainWnd);
    _stackedLayout->addWidget(_settingsWnd);
    this->setLayout(_stackedLayout);
}

void NotifyWnd::initMainWnd() {
    _topBar = new TopBar(this);
    _footAreaWnd = new FootAreaWnd(this);
    _mainProjWnd = new QScrollArea(this);
    _mainProjWnd->setWidgetResizable(true);
    _projWnd = new ProjWnd(this);
    _mainProjWnd->setWidget(_projWnd);
    QVBoxLayout *vb = new QVBoxLayout;
    _searchEdit = new QComboBox(this);
    _searchEdit->setFixedHeight(25);
    _searchEdit->setEditable(true);
    // _searchEdit->setPlaceholderText(tr("filter..."));
    _searchEdit->addItem("asd1");
    _searchEdit->addItem("asd2");
    _searchEdit->addItem("asd3");
    _footAreaWnd->setMaximumHeight(400);
    vb->setMargin(0);
    vb->setContentsMargins(1, 1, 1, 1);
    vb->addWidget(_topBar);
    vb->addWidget(_searchEdit);
    vb->addWidget(_mainProjWnd);
    vb->addWidget(_footAreaWnd);
    vb->setSpacing(1);
    _footAreaWnd->hide();
    _mainWnd->setLayout(vb);
    connect(_topBar, &TopBar::hideWnd, this, &NotifyWnd::hideWnd);
    connect(_topBar, &TopBar::showSettingsWnd, this, [&] {
        _stackedLayout->setCurrentIndex(1);
    });
}

void NotifyWnd::initSettingsWnd() {
    connect(_settingsWnd, &CSettingsWnd::turnBack, this, [&] {
        _stackedLayout->setCurrentIndex(0);
    });
}

void NotifyWnd::initSystemTray () {
    sysTrayIco = new QSystemTrayIcon(this);
    this->installEventFilter (sysTrayIco);
    tray_menu = new QMenu();
    showAction = new QAction(tr("show"), this);
    quitAction = new QAction(tr("quit"), this);
    tray_menu->addAction(showAction);
    tray_menu->addAction(quitAction);
    sysTrayIco->setContextMenu (tray_menu);

    sysTrayIco->setIcon(QIcon(QApplication::applicationDirPath() +  "/skin/projIcon.png"));
    sysTrayIco->show ();
    connect (sysTrayIco, &QSystemTrayIcon::activated, [=](QSystemTrayIcon::ActivationReason reson){
        if (reson == QSystemTrayIcon::ActivationReason::Context) { return; }
        // if (qApp->activeWindow() != this) { showWnd(); return; }
        !_isShow ? showWnd () : hideWnd ();
    });
    connect (quitAction, &QAction::triggered, [=]{ qApp->exit (); });
}

void NotifyWnd::showWnd () {
    auto animModel = QEasingCurve::InCubic;
    QDesktopWidget *desktopWidget = QApplication::desktop();
    // 获取可用桌面大小
    int curMonitor = desktopWidget->screenNumber(this);
    QRect deskRect = desktopWidget->availableGeometry(curMonitor);
    this->show ();
    // this->raise();
    this->activateWindow();
    _isShow = true;
    QPropertyAnimation *act = new QPropertyAnimation(this, "geometry");
    act->setDuration (200);
    act->setStartValue (QRect(deskRect.width (), 0, 0, deskRect.height ()));
    act->setEndValue (QRect(deskRect.width () - 400, 0, 400, deskRect.height ()));
    act->setEasingCurve (animModel);
    act->start (QAbstractAnimation::DeleteWhenStopped);
}

void NotifyWnd::hideWnd () {
    auto animModel = QEasingCurve::InCubic;
    QDesktopWidget *desktopWidget = QApplication::desktop();
    // 获取可用桌面大小
    int curMonitor = desktopWidget->screenNumber(this);
    QRect deskRect = desktopWidget->availableGeometry(curMonitor);
    _isShow = false;
    QPropertyAnimation *act = new QPropertyAnimation(this, "geometry");
    act->setDuration (200);
    act->setStartValue (this->geometry ());
    act->setEndValue (QRect(deskRect.width (), 0, 0, deskRect.height ()));
    act->setEasingCurve (animModel);
    act->start (QAbstractAnimation::DeleteWhenStopped);
    connect (act, &QPropertyAnimation::finished, [=]{this->hide ();});
}

void NotifyWnd::loadLocalData() {
    auto path = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
    path = path.mid(0, path.lastIndexOf("/"));
    path += "/SiderBarHelper/config/localData.json";
    qDebug() << path;
    QFile file(path);
    if (!file.open(QFile::ReadOnly | QFile::Text)) { 
        return;
    }
    QString strData = file.readAll();
    file.close();

    QJsonDocument doc = QJsonDocument::fromJson(strData.toLocal8Bit().data());
    if (doc.isNull()) { 
        qDebug() << "error data format";
        return;
    }
    QJsonObject jsonObj = doc.object();
    auto a = jsonObj.find("ProjGroupList")->toArray();
    for (int i = 0; i < a.size(); i++) {
        _projWnd->addNewProjGroup(a.at(i).toObject());
    }
}

void NotifyWnd::saveLocalData() {
    QJsonDocument doc;
    doc.setObject(_projWnd->getJsonData());
    QByteArray ba = doc.toJson(QJsonDocument::Compact);
    auto path = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
    path = path.mid(0, path.lastIndexOf("/"));
    path += "/SiderBarHelper/config/localData.json";
    QFile file(path);
    if (!file.open(QFile::Text | QFile::Truncate | QFile::WriteOnly)) { return; }
    file.write(ba);
    file.close();
}


bool NotifyWnd::eventFilter (QObject *obj, QEvent *evt) {

    return QWidget::eventFilter (obj, evt);
}

bool NotifyWnd::nativeEventFilter(const QByteArray &eventType, void *message, long *result){
    if (eventType == "windows_generic_MSG") {
        PMSG pMsg = reinterpret_cast<MSG*>(message);
        if (pMsg->message == WM_KILLFOCUS) {
            // this->hideWnd ();
        }

        if ((WM_HOTKEY == pMsg->message) 
            && ((UINT)LOWORD(pMsg->lParam) == MOD_ALT) 
            && ((UINT)HIWORD(pMsg->lParam) == VK_F8)) {
            isHidden() ? showWnd() : hideWnd();
            return true;
        }
    }

    return false;
    // return QWidget::nativeEventFilter(eventType, message, result);
}